package com.qike.duola.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.qike.duola.domain.*;
import com.qike.duola.dto.*;
import com.qike.duola.enums.ErrorEnums;
import com.qike.duola.enums.GoodsTypeEnums;
import com.qike.duola.enums.StatusEnums;
import com.qike.duola.mapper.DuolaFormulaGoodsMapper;
import com.qike.duola.mapper.DuolaFormulaMapper;
import com.qike.duola.mapper.DuolaGoodsMapper;
import com.qike.duola.service.DuolaDeptService;
import com.qike.duola.service.DuolaFormulaService;
import com.qike.duola.vo.*;
//import com.sun.org.apache.bcel.internal.generic.NEW;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;

/**
 * @Author: Eric.zhou
 * @Date: 2020/9/9 18:18
 */
@Service
public class DuolaFormulaServiceImpl implements DuolaFormulaService {
    private static final Logger logger = LoggerFactory.getLogger(DuolaFormulaServiceImpl.class);
    @Autowired
    private DuolaFormulaMapper duolaFormulaMapper;
    @Autowired
    private DuolaFormulaGoodsMapper duolaFormulaGoodsMapper;
    @Autowired
    private DuolaGoodsMapper duolaGoodsMapper;


    /**
     * 添加配比
     *
     * @param formulaAddDto
     */
    @Override
    public void formulaAdd(FormulaAddDto formulaAddDto) throws Exception {
        // 添加配比
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "添加配比" + JSON.toJSON(formulaAddDto));
        //查询是否作为模板的
        if (StatusEnums.NO.getEcode().equals(formulaAddDto.getIsTemplate())){
            DuolaFormulaExample formulaExample = new DuolaFormulaExample();
            formulaExample.createCriteria().andStatusEqualTo(StatusEnums.NO.getEcode()).andConcreteIdEqualTo(formulaAddDto.getConcreteId()).andIsTemplateEqualTo(StatusEnums.NO.getEcode());
            List<DuolaFormula> duolaFormulas = duolaFormulaMapper.selectByExample(formulaExample);
            if (duolaFormulas.size()>0){
                throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
            }
        }
        DuolaFormula duolaFormula = new DuolaFormula();
        duolaFormula.setStatus(StatusEnums.NO.getEcode());
        duolaFormula.setAddTime(LocalDateTime.now());
        duolaFormula.setAddUid(userId);
        duolaFormula.setConcreteId(formulaAddDto.getConcreteId());
        duolaFormula.setFormulaName(formulaAddDto.getName());
        duolaFormula.setIsTemplate(formulaAddDto.getIsTemplate());
        duolaFormulaMapper.insertSelective(duolaFormula);
        //添加配比中基础物料信息
        for (FormulaGoodsAddDto formulaGoodsAddDto : formulaAddDto.getList()) {
            DuolaFormulaGoods duolaFormulaGoods = new DuolaFormulaGoods();
            duolaFormulaGoods.setFormulaId(duolaFormula.getId());
            duolaFormulaGoods.setGoodsId(formulaGoodsAddDto.getGoodsId());
            duolaFormulaGoods.setNum(formulaGoodsAddDto.getNum());
            duolaFormulaGoodsMapper.insertSelective(duolaFormulaGoods);
        }
    }

    /**
     * 编辑配比
     *
     * @param formulaEditDto
     */
    @Override
    public void formulaEdit(FormulaEditDto formulaEditDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "编辑配比" + JSON.toJSON(formulaEditDto));
        DuolaFormula duolaFormula = duolaFormulaMapper.selectByPrimaryKey(formulaEditDto.getId());
        if (duolaFormula == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        if (formulaEditDto.getIsTemplate()!=null&&formulaEditDto.getIsTemplate().equals(StatusEnums.NO.getEcode())){
            DuolaFormulaExample duolaFormulaExample = new DuolaFormulaExample();
            duolaFormulaExample.createCriteria().andConcreteIdEqualTo(formulaEditDto.getConcreteId()).andIsTemplateEqualTo(StatusEnums.NO.getEcode()).andStatusEqualTo(StatusEnums.NO.getEcode());
            List<DuolaFormula> duolaFormulas = duolaFormulaMapper.selectByExample(duolaFormulaExample);
            if (duolaFormulas.size()>0&&!duolaFormulas.get(0).getId().equals(duolaFormula.getId())){
                throw new Exception(ErrorEnums.HAVE_TEMPLATE.getEmsg());
            }
        }
        duolaFormula.setFormulaName(formulaEditDto.getName());
        duolaFormula.setUpdateTime(LocalDateTime.now());
        duolaFormula.setUpdateUid(userId);
        duolaFormula.setIsTemplate(formulaEditDto.getIsTemplate());
        duolaFormula.setConcreteId(formulaEditDto.getConcreteId());
        duolaFormulaMapper.updateByPrimaryKey(duolaFormula);
        //更新配比物料
        for (FormulaGoodsEditDto formulaGoodsEditDto : formulaEditDto.getList()) {
            DuolaFormulaGoods duolaFormulaGoods = new DuolaFormulaGoods();

            duolaFormulaGoods.setNum(formulaGoodsEditDto.getNum());
            duolaFormulaGoods.setFormulaId(formulaEditDto.getId());
            duolaFormulaGoods.setGoodsId(formulaGoodsEditDto.getGoodsId());
            if (formulaGoodsEditDto.getId() == null) {
                duolaFormulaGoods.setId(formulaGoodsEditDto.getId());
                duolaFormulaGoodsMapper.insertSelective(duolaFormulaGoods);
            } else {
                duolaFormulaGoods.setId(formulaGoodsEditDto.getId());
                duolaFormulaGoodsMapper.updateByPrimaryKey(duolaFormulaGoods);
            }

        }
    }

    /**
     * 删除配比
     *
     * @param deptDelDto
     */
    @Override
    public void formulaDel(DeptDelDto deptDelDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "删除配比" + JSON.toJSON(deptDelDto));
        DuolaFormula duolaFormula = duolaFormulaMapper.selectByPrimaryKey(deptDelDto.getId());
        if (duolaFormula == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        duolaFormula.setStatus(StatusEnums.YES.getEcode());
        duolaFormula.setUpdateTime(LocalDateTime.now());
        duolaFormula.setUpdateUid(userId);
        duolaFormulaMapper.updateByPrimaryKey(duolaFormula);
    }

    /**
     * 配比列表
     *
     * @param formulaListDto
     * @return
     */
    @Override
    public FormulaListVo formulaList(FormulaListDto formulaListDto) {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "配比列表" + JSON.toJSON(formulaListDto));
        List<Integer> formulaIds = new ArrayList<>();
        Set<Integer> goodsIds = new HashSet<>();
        Map<Integer, List<FormulaGoodsListVo>> DuolaFormulaGoodsMap = new HashMap<>();
        Map<Integer, DuolaGoods> duolaGoodsMap = new HashMap<>();
        FormulaListVo vo = new FormulaListVo();
        List<FormulaList> list = new ArrayList<>();
        DuolaFormulaExample formulaExample = new DuolaFormulaExample();
        DuolaFormulaExample.Criteria criteria = formulaExample.createCriteria();
        if (!StringUtils.isEmpty(formulaListDto.getName())) {
            criteria.andFormulaNameLike(formulaListDto.getName());
        }

        //获取所有配比列表
        criteria.andStatusEqualTo(StatusEnums.NO.getEcode());
        Page page = PageHelper.startPage(formulaListDto.getStartPage(), formulaListDto.getPageSize());
        List<DuolaFormula> duolaFormulas = duolaFormulaMapper.selectByExample(formulaExample);
        if (duolaFormulas.size()<=0){
            return vo;
        }
        for (DuolaFormula duolaFormula : duolaFormulas) {
            formulaIds.add(duolaFormula.getId());
        }
        //获取所有配比物料列表
        DuolaFormulaGoodsExample duolaFormulaGoodsExample = new DuolaFormulaGoodsExample();
        duolaFormulaGoodsExample.createCriteria().andFormulaIdIn(formulaIds);
        List<DuolaFormulaGoods> duolaFormulaGoods = duolaFormulaGoodsMapper.selectByExample(duolaFormulaGoodsExample);
        for (DuolaFormulaGoods duolaFormulaGood : duolaFormulaGoods) {
            goodsIds.add(duolaFormulaGood.getGoodsId());
        }

        List<Integer> goodsIdsList = new ArrayList<>(goodsIds);
        //获取物料表
        DuolaGoodsExample duolaGoodsExample = new DuolaGoodsExample();
        duolaGoodsExample.createCriteria().andIdIn(goodsIdsList);
        List<DuolaGoods> duolaGoods = duolaGoodsMapper.selectByExample(duolaGoodsExample);
        for (DuolaGoods duolaGood : duolaGoods) {
            duolaGoodsMap.put(duolaGood.getId(), duolaGood);
        }

        for (DuolaFormulaGoods duolaFormulaGood : duolaFormulaGoods) {
            FormulaGoodsListVo formulaGoodsListVo = new FormulaGoodsListVo();
            formulaGoodsListVo.setId(duolaFormulaGood.getId());
            formulaGoodsListVo.setGoodsId(duolaFormulaGood.getGoodsId());
            formulaGoodsListVo.setNum(duolaFormulaGood.getNum());
            formulaGoodsListVo.setGoodsName(duolaGoodsMap.get(duolaFormulaGood.getGoodsId()).getGoodsName());
            formulaGoodsListVo.setGoodsUnit(duolaGoodsMap.get(duolaFormulaGood.getGoodsId()).getGoodsUnit());
            if (DuolaFormulaGoodsMap.get(duolaFormulaGood.getFormulaId()) == null) {
                List<FormulaGoodsListVo> listVos = new ArrayList<>();
                listVos.add(formulaGoodsListVo);
                DuolaFormulaGoodsMap.put(duolaFormulaGood.getFormulaId(), listVos);
            } else {
                List<FormulaGoodsListVo> listVos = DuolaFormulaGoodsMap.get(duolaFormulaGood.getFormulaId());
                listVos.add(formulaGoodsListVo);
                DuolaFormulaGoodsMap.put(duolaFormulaGood.getFormulaId(), listVos);
            }

        }
        for (DuolaFormula duolaFormula : duolaFormulas) {
            FormulaList formulaList = new FormulaList();
            formulaList.setId(duolaFormula.getId());
            formulaList.setName(duolaFormula.getFormulaName());
            formulaList.setList(DuolaFormulaGoodsMap.get(duolaFormula.getId()));
            formulaList.setIsTemplate(duolaFormula.getIsTemplate()==null?0:duolaFormula.getIsTemplate());
            list.add(formulaList);
        }
        vo.setList(list);
        vo.setTotal(page.getTotal());
        return vo;
    }

    /**
     * 配比详情
     *
     * @param id
     * @return
     */
    @Override
    public FormulaInfoVo formulaInfo(Integer id) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "配比详情" + JSON.toJSON(id));
        //获取配比
        DuolaFormula duolaFormula = duolaFormulaMapper.selectByPrimaryKey(id);
        if (duolaFormula == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        //获取配比的具体物料信息
        Set<Integer> goodsIds = new HashSet<>();
        Map<Integer, DuolaGoods> goodsMap = new HashMap<>();
        List<FormulaGoodsListVo> list = new ArrayList<>();
        DuolaFormulaGoodsExample example = new DuolaFormulaGoodsExample();
        example.createCriteria().andFormulaIdEqualTo(duolaFormula.getId());
        List<DuolaFormulaGoods> goodsList = duolaFormulaGoodsMapper.selectByExample(example);
        for (DuolaFormulaGoods duolaFormulaGoods : goodsList) {
            goodsIds.add(duolaFormulaGoods.getGoodsId());
        }

        goodsIds.add(duolaFormula.getConcreteId());
        //根据配比物料信息 查询物料表中的数据
        List<Integer> goodsIdsList = new ArrayList<>(goodsIds);
        DuolaGoodsExample goodsExample = new DuolaGoodsExample();
        goodsExample.createCriteria().andIdIn(goodsIdsList);
        List<DuolaGoods> duolaGoods = duolaGoodsMapper.selectByExample(goodsExample);
        for (DuolaGoods duolaGood : duolaGoods) {
            goodsMap.put(duolaGood.getId(), duolaGood);
        }
        //拼接返回数据
        for (DuolaFormulaGoods duolaFormulaGoods : goodsList) {
            FormulaGoodsListVo vo = new FormulaGoodsListVo();
            vo.setNum(duolaFormulaGoods.getNum());
            vo.setGoodsId(duolaFormulaGoods.getGoodsId());
            vo.setId(duolaFormulaGoods.getId());
            vo.setGoodsName(goodsMap.get(duolaFormulaGoods.getGoodsId()).getGoodsName());
            vo.setGoodsUnit(goodsMap.get(duolaFormulaGoods.getGoodsId()).getGoodsUnit());
            list.add(vo);
        }
        FormulaInfoVo vo = new FormulaInfoVo();
        vo.setId(duolaFormula.getId());
        vo.setName(duolaFormula.getFormulaName());
        vo.setConcreteId(duolaFormula.getConcreteId());
        vo.setConcreteName(goodsMap.get(duolaFormula.getConcreteId()).getGoodsName());
        vo.setList(list);
        return vo;
    }

    /**
     * 配比编辑物料跳转
     *
     * @param id
     * @return
     */
    @Override
    public FormulaInfoVo formulaEditGoodsJump(Integer id) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "配比编辑物料跳转" + JSON.toJSON(id));
        //获取配比
        DuolaFormula duolaFormula = duolaFormulaMapper.selectByPrimaryKey(id);
        if (duolaFormula == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        //获取配比的具体物料信息
        Set<Integer> goodsIds = new HashSet<>();
        Map<Integer, DuolaGoods> goodsMap = new HashMap<>();
        List<FormulaGoodsListVo> list = new ArrayList<>();
        DuolaFormulaGoodsExample example = new DuolaFormulaGoodsExample();
        example.createCriteria().andFormulaIdEqualTo(duolaFormula.getId());
        List<DuolaFormulaGoods> goodsList = duolaFormulaGoodsMapper.selectByExample(example);
        for (DuolaFormulaGoods duolaFormulaGoods : goodsList) {
            goodsIds.add(duolaFormulaGoods.getGoodsId());
        }
        //根据配比物料信息 查询物料表中的数据
        List<Integer> goodsIdsList = new ArrayList<>(goodsIds);
        DuolaGoodsExample goodsExample = new DuolaGoodsExample();
        goodsExample.createCriteria().andGoodsTypeNotEqualTo(GoodsTypeEnums.CONCRETE.getEcode()).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<DuolaGoods> duolaGoods = duolaGoodsMapper.selectByExample(goodsExample);
        for (DuolaGoods duolaGood : duolaGoods) {
            goodsMap.put(duolaGood.getId(), duolaGood);
        }
        for (Map.Entry<Integer, DuolaGoods> integerDuolaGoodsEntry : goodsMap.entrySet()) {
            //拼接返回数据
            for (DuolaFormulaGoods duolaFormulaGoods : goodsList) {
                FormulaGoodsListVo vo = new FormulaGoodsListVo();
                if (!integerDuolaGoodsEntry.getKey().equals(duolaFormulaGoods.getGoodsId())) {
                    vo.setNum(new Double(0));
                    vo.setGoodsId(integerDuolaGoodsEntry.getKey());
                    vo.setGoodsName(integerDuolaGoodsEntry.getValue().getGoodsName());
                    vo.setGoodsUnit(integerDuolaGoodsEntry.getValue().getGoodsUnit());
                } else {
                    vo.setNum(duolaFormulaGoods.getNum());
                    vo.setGoodsId(duolaFormulaGoods.getGoodsId());
                    vo.setId(duolaFormulaGoods.getId());
                    vo.setGoodsName(integerDuolaGoodsEntry.getValue().getGoodsName());
                    vo.setGoodsUnit(integerDuolaGoodsEntry.getValue().getGoodsUnit());
                }

                list.add(vo);
            }
        }

        FormulaInfoVo vo = new FormulaInfoVo();
        vo.setId(duolaFormula.getId());
        vo.setName(duolaFormula.getFormulaName());
        vo.setList(list);
        return vo;
    }

    /**
     * 配比添加物料跳转
     *
     * @return
     */
    @Override
    public List<FormulaAddGoodsJumpVo> formulaAddGoodsJump() {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "配比添加物料跳转");
        List<FormulaAddGoodsJumpVo> list = new ArrayList<>();
        DuolaGoodsExample goodsExample = new DuolaGoodsExample();
        goodsExample.createCriteria().andGoodsTypeNotEqualTo(GoodsTypeEnums.CONCRETE.getEcode()).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<DuolaGoods> duolaGoods = duolaGoodsMapper.selectByExample(goodsExample);
        for (DuolaGoods duolaGood : duolaGoods) {
            FormulaAddGoodsJumpVo vo = new FormulaAddGoodsJumpVo();
            vo.setGoodsId(duolaGood.getId());
            vo.setGoodsName(duolaGood.getGoodsName());
            vo.setGoodsUnit(duolaGood.getGoodsUnit());
            list.add(vo);
        }
        return list;
    }

    /**
     * 配比下拉
     *
     * @param name
     * @param goodsId
     * @return
     */
    @Override
    public List<FormulaPullListVo> formulaPullList(String name, Integer goodsId) {
        List<FormulaPullListVo> listVos = new ArrayList<>();
        DuolaFormulaExample example = new DuolaFormulaExample();
        DuolaFormulaExample.Criteria criteria = example.createCriteria();
        if (!StringUtils.isEmpty(name)){
            criteria.andFormulaNameLike(name);
        }
        criteria.andConcreteIdEqualTo(goodsId).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<DuolaFormula> duolaFormulas = duolaFormulaMapper.selectByExample(example);
        for (DuolaFormula duolaFormula : duolaFormulas) {
            FormulaPullListVo vc = new FormulaPullListVo();
            vc.setId(duolaFormula.getId());
            vc.setName(duolaFormula.getFormulaName());
            listVos.add(vc);
        }
        return listVos;
    }

    /**
     * 根据砼品种获取模板数据
     *
     * @param concreteId
     * @return
     */
    @Override
    public List<FormulaGoodsListVo> getTemplateByConcreteId(Integer concreteId) {
        List<FormulaGoodsListVo> Volist = new ArrayList<>();
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "根据砼品种获取模板数据" + JSON.toJSON(concreteId));
        Map<Integer, DuolaGoods> goodsMap = new HashMap<>();
        Map<Integer, Double> goodsNumMap = new HashMap<>();
        List<FormulaGoodsListVo> list = new ArrayList<>();
        List<DuolaFormulaGoods> goodsList = new ArrayList<>();
        //获取配比
//        DuolaFormula duolaFormula = duolaFormulaMapper.s(id);
        DuolaFormulaExample formulaExample = new DuolaFormulaExample();
        formulaExample.createCriteria().andStatusEqualTo(StatusEnums.NO.getEcode()).andIsTemplateEqualTo(StatusEnums.NO.getEcode()).andConcreteIdEqualTo(concreteId);
        List<DuolaFormula> duolaFormulas = duolaFormulaMapper.selectByExample(formulaExample);
        if (duolaFormulas.size()>0 ) {
//            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
            //获取配比的具体物料信息
            DuolaFormulaGoodsExample example = new DuolaFormulaGoodsExample();
            example.createCriteria().andFormulaIdEqualTo(duolaFormulas.get(0).getId());
            goodsList = duolaFormulaGoodsMapper.selectByExample(example);
            for (DuolaFormulaGoods duolaFormulaGoods : goodsList) {
                goodsNumMap.put(duolaFormulaGoods.getGoodsId(),duolaFormulaGoods.getNum());
            }
        }
        //根据配比物料信息 查询物料表中的数据
        DuolaGoodsExample goodsExample = new DuolaGoodsExample();
        goodsExample.createCriteria().andGoodsTypeEqualTo(GoodsTypeEnums.PRODUCT.getEcode()).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<DuolaGoods> duolaGoods = duolaGoodsMapper.selectByExample(goodsExample);
        for (DuolaGoods duolaGood : duolaGoods) {
            FormulaGoodsListVo vo = new FormulaGoodsListVo();
            Integer id = duolaGood.getId();
            vo.setNum(new Double(0));
            vo.setGoodsId(duolaGood.getId());
            vo.setGoodsName(duolaGood.getGoodsName());
            vo.setGoodsUnit(duolaGood.getGoodsUnit());
            if (null!=goodsNumMap.get(id)){
                vo.setNum(goodsNumMap.get(id));
            }else {
                vo.setNum(new Double(0));
            }
            Volist.add(vo);
        }
        return Volist;
    }
}
